
// <copyright file="AbstractComponentController.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The abstract component controller.
// </summary>

namespace SubhadraSolutions.Sharp.Utils
{
    using SubhadraSolutions.Sharp.Utils.Contracts;

    // [PerfCounterCategory("Component Controllers", "Component Controllers")]
    /// <summary>
    /// The abstract component controller
    /// </summary>
    public abstract class AbstractComponentController : IComponentController
    {
        #region Constructors and Finalizers

        /// <summary>
        /// Initializes a new instance of the <see cref="AbstractComponentController"/> class.
        /// </summary>
        /// <param name="canPause">
        /// The can pause.
        /// </param>
        protected AbstractComponentController(bool canPause)
        {
            this.State = ControllableComponentState.NotStarted;
            this.SupportsPauseAndResume = canPause;
        }

        #endregion Constructors and Finalizers

        #region Public Properties

        /// <summary>
        /// Gets the state.
        /// </summary>
        public ControllableComponentState State { get; private set; }

        /// <summary>
        /// Gets a value indicating whether supports pause and resume.
        /// </summary>
        public bool SupportsPauseAndResume { get; private set; }

        #endregion Public Properties

        #region Public Methods and Operators

        /// <summary>
        /// The pause.
        /// </summary>
        public void Pause()
        {
            if (this.SupportsPauseAndResume)
            {
                if (this.SupportsPauseAndResume && this.State == ControllableComponentState.Idle || this.SupportsPauseAndResume && this.State == ControllableComponentState.Busy)
                {
                    this.State = ControllableComponentState.Pausing;
                    this.pause();
                    this.State = ControllableComponentState.Paused;
                }
            }
        }

        /// <summary>
        /// The resume.
        /// </summary>
        public void Resume()
        {
            if (this.SupportsPauseAndResume)
            {
                if (this.State == ControllableComponentState.Paused)
                {
                    this.State = ControllableComponentState.Resuming;
                    this.resume();
                    this.State = ControllableComponentState.Idle;
                }
            }
        }

        /// <summary>
        /// The start.
        /// </summary>
        public void Start()
        {
            if (this.State == ControllableComponentState.NotStarted || this.State == ControllableComponentState.Stopped)
            {
                this.State = ControllableComponentState.Starting;
                this.start();
                this.State = ControllableComponentState.Idle;
            }
        }

        /// <summary>
        /// The started doing something.
        /// </summary>
        public void StartedDoingSomething()
        {
            this.State = ControllableComponentState.Busy;
        }

        /// <summary>
        /// The stop.
        /// </summary>
        public void Stop()
        {
            if (this.State == ControllableComponentState.Idle || this.SupportsPauseAndResume && this.State == ControllableComponentState.Busy)
            {
                this.State = ControllableComponentState.Stopping;
                this.stop();
                this.State = ControllableComponentState.Stopped;
            }
        }

        /// <summary>
        /// The stopped doing something.
        /// </summary>
        public void StoppedDoingSomething()
        {
            this.State = ControllableComponentState.Idle;
        }

        #endregion Public Methods and Operators

        #region Methods

        /// <summary>
        /// The pause.
        /// </summary>
        protected virtual void pause()
        {
        }

        /// <summary>
        /// The resume.
        /// </summary>
        protected virtual void resume()
        {
        }

        /// <summary>
        /// The start.
        /// </summary>
        protected abstract void start();

        /// <summary>
        /// The stop.
        /// </summary>
        protected abstract void stop();

        #endregion Methods
    }
}